#ifndef __TINYOS_H__
#define __TINYOS_H__

#include "tinyos_types.h"
#include "tinyos_config.h"
#include "list.h"
#include "cpu.h"

#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))

typedef u32 task_stack_t;

typedef void (*task_handle_t)(void *param);

enum task_state_e {
    TINYOS_TASK_STATE_READY,
    TINYOS_TASK_STATE_DELAYED = 1 << 1,
    TINYOS_TASK_STATE_PENDED = 1 << 2
    
};

typedef struct task_s {
    task_stack_t *stack;
    u32 stack_size;
    u32 delay_tick;
    u32 suspend_cnt;
    u32 slice;
    u32 prio;
    task_handle_t func;
    u8 state;
    struct list_head entry;
    void *param;
} task_t;

extern task_t *cur_task;
extern task_t *next_task;

u32 task_enter_critical(void);
void task_exit_critical(u32 status);
void task_init(task_t *task, task_handle_t handle, void *param, 
    task_stack_t *stack, u32 len, u32 prio);
void task_wakeup(task_t *task);
void task_schedule(void);
task_t *task_get_ready(void);
void task_sched_disable(void);
void task_sched_enable(void);
void task_sched_init(void);
void task_sched_ready(task_t *task);
void task_sched_unready(task_t *task);
void task_systick_handle(void);
void task_supend(task_t *task);
void task_resume(task_t *task);

void task_delay(u32 delay);

void app_init(void);

void os_start(void);
void os_schedule(void);
#endif
